package com.cbts.util;

/**
 * des3可逆加密算法
 */
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;

public class DES3 {

	private static final String Algorithm = "DESede"; // 定义 加密算法,可用
	private static final String[] privatekey = {"0X69rt,123@","oX*9uh2 ;","@rt&**'~ f9"}; // 定义秘钥
	
	/**
	 * 加密
	 * @param keybyte 为加密密钥，长度为24字节
	 * @param src src为被加密的数据缓冲区（源）
	 * @return byte[] encryptMode
	 */
	public static byte[] encryptMode(byte[] keybyte, byte[] src) {
		try {
			// 生成密钥
			SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);
			// 加密
			Cipher c1 = Cipher.getInstance(Algorithm);
			c1.init(Cipher.ENCRYPT_MODE, deskey);
			return c1.doFinal(src);
		} catch (java.security.NoSuchAlgorithmException e1) {
			e1.printStackTrace();
		} catch (javax.crypto.NoSuchPaddingException e2) {
			e2.printStackTrace();
		} catch (java.lang.Exception e3) {
			e3.printStackTrace();
		}
		return null;
	}

	/**
	 * 解密
	 * @param keybyte 为加密密钥，长度为24字节
	 * @param src 加密后的缓冲区
	 * @return byte[] decryptMode
	 */
	public static byte[] decryptMode(byte[] keybyte, byte[] src) {
		try {
			
			// 生成密钥
			SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);
			// 解密
			Cipher c1 = Cipher.getInstance(Algorithm);
			c1.init(Cipher.DECRYPT_MODE, deskey);
			return c1.doFinal(src);
		} catch (java.security.NoSuchAlgorithmException e1) {
			e1.printStackTrace();
		} catch (javax.crypto.NoSuchPaddingException e2) {
			e2.printStackTrace();
		} catch (java.lang.Exception e3) {
			e3.printStackTrace();
		}
		return null;
	}

	/**
	 * 转换成十六进制字符串
	 * @param b
	 * @return
	 */
	public static String byte2hex(byte[] b) {
		String hs = "";
		String stmp = "";
		for (int n = 0; n < b.length; n++) {
			stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
			if (stmp.length() == 1) {
				hs = hs + "0" + stmp;
			} else {
				hs = hs + stmp;
			}
			if (n < b.length - 1) {
				hs = hs + ":";
			}
		}
		return hs.toUpperCase();
	}
	
	
	/**
	 * 计算得到24位长的密码byte值
	 * 首先对原始密钥做MD5算hash值，再用前8位数据对应补全后8位
	 * @param strKey 任意长度的秘钥
	 * @return 24位长的密码byte值
	 * @throws Exception 秘钥不能为null或空
	 */
	public static byte[] GetKeyBytes(String strKey) throws Exception {  
		  
        if (null == strKey || strKey.length() < 1)  
            throw new Exception("key is null or empty!");  
  
        java.security.MessageDigest alg = java.security.MessageDigest.getInstance("MD5");
        alg.update(strKey.getBytes());  
  
        byte[] bkey = alg.digest();  
        int start = bkey.length;
        byte[] bkey24 = new byte[24];
        
        for (int i = 0; i < start; i++) {  
        	if (i>23) {
				break;
			}
            bkey24[i] = bkey[i];
            
        }  
  
        for (int i = start; i < 24; i++) {//为了与.net16位key兼容  
            bkey24[i] = bkey[i - start];  
        }
        return bkey24;
    }
	
	/**
	 * 用法示例
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {

		byte[] keyBytes = GetKeyBytes(DES3.getPrivatekey()[DES3.getPrivatekey().length/2]);
		byte[] keyBytes2 = GetKeyBytes(DES3.getPrivatekey()[DES3.getPrivatekey().length/2]);
		
		String szSrc = "001";
		System.out.println("加密前的字符串:" + szSrc);

		byte[] encoded = encryptMode(keyBytes, szSrc.getBytes());
		//Base64.encode(byte[])将byte[]转成String
		//Base64.decode(String)将字符串转换成byte[]
		System.out.println("加密后的字符串:" + Base64.encode(encoded));

		byte[] srcBytes = decryptMode(keyBytes2, Base64.decode(Base64.encode(encoded)));
		System.out.println("解密后的字符串:" + (new String(srcBytes)));
	}

	public static String[] getPrivatekey() {
		return privatekey;
	}
	
}
